package com.common.base.app.fragment

import android.annotation.SuppressLint
import android.content.DialogInterface
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.os.Bundle
import android.view.*
import android.widget.FrameLayout
import androidx.fragment.app.DialogFragment
import androidx.fragment.app.FragmentManager
import androidx.viewbinding.ViewBinding
import com.common.base.R
import com.common.base.app.extras.yes
import com.common.base.databinding.BaseDialogFragmentBinding
import com.common.base.utils.ViewUtils

abstract class BaseDialogFragment<VB : ViewBinding> : DialogFragment() {

    protected lateinit var mViewBinding: VB

    private var callback: Callback? = null

    private var contentView: View? = null

    open fun isLandscape(): Boolean = ViewUtils.isFullScreen()

    open fun getSelfHeight(): Int = ViewGroup.LayoutParams.MATCH_PARENT

    open fun getSelfWidth(): Int = ViewGroup.LayoutParams.MATCH_PARENT

    open fun getPortInAnimation(): Int = R.style.base_pop_anim

    open fun getLandscapeInAnimation(): Int = R.style.base_pop_anim

    @SuppressLint("NotConstructor")
    open fun BaseDialogFragment() {
    }

    override fun show(manager: FragmentManager, tag: String?) {
//        super.show(manager, tag)
        isShowing().yes { return }
        try {
            val c = Class.forName("androidx.fragment.app.DialogFragment")
            val con = c.getConstructor()
            val obj = con.newInstance()
            val dismissed = c.getDeclaredField("mDismissed")
            dismissed.isAccessible = true
            dismissed.set(obj, false)
            val shownByMe = c.getDeclaredField("mShownByMe")
            shownByMe.isAccessible = true
            shownByMe.set(obj, false)
        } catch (e: Exception) {
            e.printStackTrace()
        }

        if (isAdded && !isRemoving){
            //如果已经添加过 则先进行移除
           dismiss()
        }
        manager.beginTransaction().remove(this).add(this, tag).commitAllowingStateLoss()
    }

    fun show(manager: FragmentManager) {
        show(manager, "commonTag")
    }

    open fun release() {
        dismissPop()
    }

    open fun dismissPop() {
        dismiss()
    }

    override fun dismiss() {
        try {
            dismissAllowingStateLoss()
            super.dismiss()
        } catch (t: Throwable) {
            t.printStackTrace()
        }
    }

    abstract fun getViewBinding(): VB

    open fun initView(view: View) {}

    open fun initEvent() {}

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setStyle(getStyle(), theme)
    }

    open fun getStyle(): Int = STYLE_NO_FRAME

    open fun setShowPosition() {
        val params = dialog?.window?.attributes
        params?.gravity = Gravity.BOTTOM
        params?.windowAnimations = R.style.base_pop_anim
        dialog?.window?.attributes = params
    }

    //设置弹框剧中显示
    fun setShowPositionCenter() {
        val params = dialog?.window?.attributes
        params?.gravity = Gravity.CENTER
        params?.windowAnimations = 0
        dialog?.window?.attributes = params
    }

    open fun initPosition() {
        setShowPosition()
        dialog?.window?.requestFeature(Window.FEATURE_NO_TITLE)
        dialog?.window?.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
        dialog?.setCanceledOnTouchOutside(isCanceledOnTouchOutside())
        dialog?.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
    }

    open fun getLayoutParams(): FrameLayout.LayoutParams? {
        return null
    }

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        initPosition()
        isCancelable = getCancelable()
        val binding = BaseDialogFragmentBinding.inflate(inflater, container, false)
        mViewBinding = getViewBinding()
        contentView = mViewBinding.root

        val layoutParams = getLayoutParams()
        if (layoutParams != null) {
            binding.contentParent.addView(contentView, layoutParams)
        } else {
            binding.contentParent.addView(contentView)
        }
        contentView?.let {
            initView(it)
        }
        initEvent()
        return binding.root
    }

    fun isShowing(): Boolean {
        return this.dialog?.isShowing ?: false
    }

    open fun getCancelable(): Boolean = true
    open fun isCanceledOnTouchOutside(): Boolean = true

    override fun onResume() {
        super.onResume()
        val width = getSelfWidth()
        val height = getSelfHeight()
        dialog?.window?.setLayout(width, height)
    }

    fun setListener(callback: Callback) {
        this.callback = callback
    }

    interface Callback {
        fun onDialogShow()
        fun onDialogDismiss()
    }

    override fun onStart() {
        super.onStart()
        callback?.onDialogShow()
    }

    override fun onDismiss(dialog: DialogInterface) {
        super.onDismiss(dialog)
        callback?.onDialogDismiss()
        callback = null
        contentView = null
        release()
    }
}
